<?php

namespace haibao\erp\data\user;

use haibao\erp\model\filter\user\User as UserFilter;

class User extends \haibao\erp\data\BaseMysql{
	public function __construct(){
		parent::__construct('\haibao\erp\model\data\user\User');
	}
	
	
	public function getUserByName($userName){
	    $model = null;
	    $sql = 'select u.*,g.GroupId from User u left join UserGroup g on u.Id=g.UserId where u.UserName=%s';
	    $result = $this->query($sql,array($userName));
	    while ($result->fetch_assoc()){
	        if (!$model){
	            $model = new \haibao\erp\model\data\user\User();
	            foreach($model->getKeyMap() as $keyName=>$keyType){
	                if (!($keyType instanceof \haibao\frame\data\datafield\RelationOneField || $keyType instanceof \haibao\frame\data\datafield\RelationManyField)){
	                    $model->$keyName = $result->getData($keyType->getFieldName());
	                }
	            }
	            $model->Groups = array();
	        }
	        $groupId = $result->getData('GroupId');
	        if ($groupId){
	            array_push($model->Groups,$groupId);
	        }
	    }
	    return $model;
	}
	
	public function getUserByEmail($email,$isEffect = true){
	    $data = null;
	    $sql = 'select * from `User` where Email=%s';
	    if($isEffect){
	        $sql .= 'and Status='.\haibao\erp\model\data\user\User::STATUS_ENABLE;
	    }
	    $result = $this->query($sql,array($email));
	    while ($row = $result->fetch_assoc()){
	        $data = new \haibao\erp\model\data\user\User();
	        $data->loadArray($row);
	    }
	
	    return $data;
	}
	
	
	public function getUserByMobile($mobile,$isEffect = true){
	    $data = null;
	    $sql = 'select * from `User` where Mobile=%s';
	    if($isEffect){
	        $sql .= 'and Status='.\haibao\erp\model\data\user\User::STATUS_ENABLE;
	    }
	    $result = $this->query($sql,array($mobile));
	    while ($row = $result->fetch_assoc()){
	        $data = new \haibao\erp\model\data\user\User();
	        $data->loadArray($row);
	    }
	
	    return $data;
	}
	

	public function getUserById($id){
	    $cache = new \haibao\erp\cache\User();
	    $model = $cache->getUser($id);
	    $model = null;
	    if (!$model){
	        //$sql = 'select u.*,g.GroupId from User u left join UserGroup g on u.Id=g.UserId where u.Id=%s';
	        $sql = 'select u.*,g.GroupId,m.UserId as LowerUserId from `User` u left join UserGroup g on u.Id=g.UserId LEFT JOIN UserLeaderMap m on  m.LeaderId = u.Id where u.Id=%s';
	        $result = $this->query($sql,array($id));
	        while ($result->fetch_assoc()){
	            if (!$model){
	                $model = new \haibao\erp\model\data\user\User();
	                foreach($model->getKeyMap() as $keyName=>$keyType){
	                    if (!($keyType instanceof \haibao\frame\data\datafield\RelationOneField || $keyType instanceof \haibao\frame\data\datafield\RelationManyField)){
	                        $model->$keyName = $result->getData($keyType->getFieldName());
	                    }
	                }
	                $model->Groups = array();
	            }
	            $groupId = $result->getData('GroupId');
	            if ($groupId){
	                array_push($model->Groups,$groupId);
	            }
	
	            $lowerUserId = $result->getData('LowerUserId');
	            if($lowerUserId){
	                if(!in_array($lowerUserId,$model->LowerUser)){
	                    array_push($model->LowerUser,$lowerUserId);
	                }
	            }
	        }
	
	        if($model){
	            if($model->Groups) {
	                	
	                $model->Groups = array_flip(array_flip($model->Groups));
	                //取出用户同组的其他用户Id
	                $sql = 'select g.* from UserGroup g where g.GroupId in ('.implode(',',$model->Groups).')  and g.UserId not in (select m.LeaderId FROM UserLeaderMap m where m.UserId = %s and m.UserId <> m.LeaderId) group BY g.UserId';
	
	                $result = $this->query($sql,array($id));
	                while ($result->fetch_assoc()){
	                    array_push($model->SameUser,$result->getData('UserId'));
	                }
	            }
	            if($model->LowerUser){
	                $lowerUser = implode(',',$model->LowerUser);
	                $sql = 'select * from User where Id in ('.$lowerUser.') and Status=%s';
	                $result = $this->query($sql,array(\haibao\erp\model\data\user\User::STATUS_DIMISSION));
	                while ($result->fetch_assoc()){
	                    array_push($model->DimissionUser,$result->getData('Id'));
	                }
	            }
	        }
	        	
	        $cache->setUser($model);
	    }
	    return $model;
	}
	
	public function add($model){
	    $this->beginTranscation();
	    try {
	        parent::add($model);
	        	
	        if($model->Groups){
	            $this->addUserGroups($model->Id, $model->Groups);
	        }
	        	
	        $sql = 'insert into UserLeaderMap(UserId, LeaderId)
					select UserId, LeaderId from (
						(select %s as UserId, LeaderId from UserLeaderMap where UserId = %s)
						union
						(select %s,%s from UserLeaderMap limit 1)
					) a';
	        $this->query($sql, array(
	            $model->Id, $model->LeaderId, $model->Id, $model->Id,
	        ));
	        	
	        if($model->LeaderId){
	            $this->removeUserCacheById($model->LeaderId);
	        }
	    } catch (\Exception $e) {
	        $this->rollback();
	        throw $e;
	    }
	    $this->endTranscation();
	}
	
	public function removeUserCacheById($id){
	    $cache = new \haibao\erp\cache\User();
	    $cache->removeUserById($id);
	    $leaderId = $this->getUserLeaderById($id);
	    if($leaderId != $id){
	        $this->removeUserCacheById($leaderId);
	    }
	}
	
	public function removeUserGroups($id){
	    $sql = 'delete from UserGroup where UserId=%s';
	    $this->query($sql,array($id));
	}
	
	private function addUserGroups($id, $Groups){
	    $sql = 'insert into UserGroup(UserId,GroupId) values';
	    $arrSql = $arrValues = array();
	    foreach($Groups as $group){
	        array_push($arrSql,'(%s,%s)');
	        array_push($arrValues, $id);
	        array_push($arrValues, $group);
	    }
	    $sql .= implode(',', $arrSql);
	    $this->query($sql, $arrValues);
	    $this->removeUserCacheById($id);
	}
	
	private function getUserLeaderById($userId){
	    $leaderId = 0;
	    $sql = 'select LeaderId from User where Id=%s';
	    $result = $this->query($sql,array($userId));
	    while ($result->fetch_assoc()){
	        $leaderId = $result->getData('LeaderId');
	    }
	
	    return $leaderId;
	}
	/**
	 * 获取用户的下级用户
	 * @param : $userId 用户ID
	 * @param : $exceptSelf 是否剔除自己，默认为不剔除
	 */
	public function getLowerUserById($userId,$exceptSelf=false){
	    $exceptCondition = '';
	    $userIdArr = array();
	    if($exceptSelf){
	        $exceptCondition = ' and UserId <> LeaderId';
	    }
	    $sql = 'select UserId from `UserLeaderMap` where LeaderId=%s'.$exceptCondition;
	    $result = $this->query($sql,array($userId));
	    while ($result->fetch_assoc()){
	
	        array_push($userIdArr, $result->getData('UserId'));
	    }
	    return $userIdArr;
	}
	
	public function getUserNameByIds($ids){
	
	    $userFilter = new UserFilter();
	    $userFilter->select(array(
	        UserFilter::CONDITION_FIELD_NAME_REAL_NAME,
	        UserFilter::CONDITION_FIELD_NAME_USER_NAME,
	        UserFilter::CONDITION_FIELD_NAME_ID
	    ));
	    $userFilter->where(UserFilter::CONDITION_FIELD_NAME_ID, \haibao\frame\data\query\Condition::CONDITION_IN, $ids);
	
	    $users =  parent::getAll($userFilter);
	    $usertNames = array();
	    if($users){
	        foreach($users as $key=>$user){
	            $usertNames[$user->Id] = $user->RealName;
	        }
	    }
	    return $usertNames;
	}
	
	public function getUserByJobNum($jobNum){
	    $data = null;
	    $sql = 'select * from User Where JobNum=%s limit 1';
	    $result = $this->query($sql,array($jobNum));
	    while ($row = $result->fetch_assoc()){
	        $data = new \haibao\erp\model\data\user\User();
	        $data->loadArray($row);
	    }
	
	    return $data;
	}
	
	public function getUsersByAllName($name){
	    $data = array();
	    $name = '%' . $name . '%';
	    $sql = 'select * from User where RealName like %s or UserName like %s';
	    $result = $this->query($sql,array($name,$name));
	
	    while ($row = $result->fetch_assoc()){
	        $model = new \haibao\erp\model\data\user\User();
	        $model->loadArray($row);
	        array_push($data,$model);
	    }
	
	    return $data;
	}
	
	public function updateById($id,$arrSet){
	    $this->beginTranscation();
	    try {
	        parent::updateById($id, $arrSet);
	        	
	        if(isset($arrSet[\haibao\erp\model\filter\user\User::CONDITION_FIELD_NAME_GROUPS])){
	            $this->updateUserGroups($id, $arrSet[\haibao\erp\model\filter\user\User::CONDITION_FIELD_NAME_GROUPS]);
	        }/* else{
	        $this->removeUserGroups($id);
	        } */
	        	
	        if (isset($arrSet[\haibao\erp\model\filter\user\User::CONDITION_FIELD_NAME_LEADER_ID])){
	            $leadId = $arrSet[\haibao\erp\model\filter\user\User::CONDITION_FIELD_NAME_LEADER_ID];
	
	            $sql = 'delete from UserLeaderMap where Id in (
						select Id from
							(
								select map.Id from UserLeaderMap map inner join (
									select * from
									(
										select a.LeaderId from UserLeaderMap a where a.UserId = %s and a.LeaderId <> %s
									) a
									join
									(
										select b.UserId from UserLeaderMap b where b.LeaderId = %s
									) b
								) tmp ON map.LeaderId = tmp.LeaderId and map.UserId = tmp.UserId
							) a
						)';
	            $this->query($sql, array_pad(array(), 3, $id));
	            	
	            $sql = 'insert into UserLeaderMap (UserId, LeaderId) select  b.UserId,a.LeaderId from
						(
							select LeaderId from UserLeaderMap where UserId = %s
						) a join (
							select UserId from UserLeaderMap where LeaderId = %s
						) b';
	            $this->query($sql, array(
	                $leadId, $id
	            ));
	        }
	        	
	        $this->removeUserCacheById($id);
	    } catch (\Exception $e) {
	        $this->rollback();
	        throw $e;
	    }
	    $this->endTranscation();
	}
	
	public function updateStatus($id, $status){
		$this->beginTranscation();
		try {
			parent::updateById($id, array('Status'=>$status));
				
			$this->removeUserCacheById($id);
		} catch (\Exception $e) {
			$this->rollback();
			throw $e;
		}
		$this->endTranscation();
	}
	
	public function updateUserGroups($id, $Groups){
		$this->beginTranscation();
		try{
			$this->removeUserGroups($id);
			$this->addUserGroups($id, $Groups);
			//$this->removeUserCacheById($id);
		} catch (\Exception $e) {
			$this->rollback();
			throw $e;
		}
		$this->endTranscation();
	}
	
	/**
	 * 设置用户组用户
	 * @param unknown_type $groupId
	 * @param unknown_type $userIds
	 */
	public function setGroupUser($groupId,$userIds){
		$this->beginTranscation();
		try{
			$sql = 'delete from UserGroup where GroupId=%s and UserId in ('.implode(',', $userIds).')';
			$this->query($sql,array($groupId));
				
			$sql = 'insert into UserGroup(UserId,GroupId) values';
			$arrSql = $arrValues = array();
			foreach($userIds as $userId){
				if($userId){
					array_push($arrSql,'(%s,%s)');
					array_push($arrValues, $userId);
					array_push($arrValues, $groupId);
					$this->removeUserCacheById($userId);
				}
			}
			$sql .= implode(',', $arrSql);
			$this->query($sql, $arrValues);
		} catch (\Exception $e) {
			$this->rollback();
			throw $e;
		}
		$this->endTranscation();
	}
	
}
